package com.rfid.webp2plib;

import android.content.Context;
import android.os.Handler;
import android.util.Log;

import com.google.gson.Gson;

import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.IceCandidate;
import org.webrtc.MediaStream;
import org.webrtc.SessionDescription;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by deanliu on 2019/9/4.
 */

public class WebClientManager implements WebRtcClient.PeerListener,SignalClient.SignalListener{

    private static WebClientManager clientManager;

    private static final String TAG = "ClientManager:webrtc";

    Handler mHandler = new Handler();

    WebRtcClient mRtcClient;
    SignalClient mSignalClient;
    private Context mContext;
    private PermissionCallBack mPermissionCallBack;

    private List<SignalClient.UserListener> mUserListeners;

    public WebClientManager(Context context) {
        mContext = context;
        mUserListeners = new ArrayList<>();
        mRtcClient = new WebRtcClient(context);
        mSignalClient = new SignalClient();
        mSignalClient.registerSignalListener(this);
        mRtcClient.registerPeerListener(this);
        mSignalClient.setUserListener(new SignalClient.UserListener() {
            @Override
            public void onLogin(String id, List<User> users) {
                System.out.println("onLogin mUserListeners size = " + mUserListeners.size());
                for (User user :users) {
                    if (id.equals(user.getId())) {
                        users.remove(user);
                        break;
                    }
                }
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        for (SignalClient.UserListener userListener : mUserListeners) {
                            System.out.println("onLogin > " + id);
                            userListener.onLogin(id,users);
                        }
                    }
                });
            }

            @Override
            public void onConnect(String id) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        for (SignalClient.UserListener userListener : mUserListeners) {
                            userListener.onConnect(id);
                        }
                    }
                });
            }

            @Override
            public void onDisconnect() {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        for (SignalClient.UserListener userListener : mUserListeners) {
                            userListener.onDisconnect();
                        }
                    }
                });
            }
        });
    }

    public static WebClientManager getClientManager(Context context) {
        if(clientManager == null) {
            clientManager = new WebClientManager(context);
        }
        return clientManager;
    }

    public void connectSignalServer() {
        if (mSignalClient.isConnect()) {
            for (SignalClient.UserListener userListener : mUserListeners) {
                userListener.onConnect(mSignalClient.getId());
            }
            login();
        } else {
            mSignalClient.connectSignalServer();
        }
    }

    public void login() {
        User.DataBean dataBean = new User.DataBean();
        dataBean.setVer(AppUtils.getVersionName(mContext));
        dataBean.setCode(AppUtils.getVersionCode(mContext)+"");
        dataBean.setPkg(AppUtils.getPackageName(mContext));
        dataBean.setName(AppUtils.getAppName(mContext));
        Gson gson = new Gson();
        mSignalClient.login(gson.toJson(dataBean));
    }

    public void registerUserChange(SignalClient.UserListener listener) {
        mUserListeners.remove(listener);
        mUserListeners.add(listener);
    }

    public void unRegisterUserChange(SignalClient.UserListener listener) {
        mUserListeners.remove(listener);
    }

    public void connectPeer(String id) {
        mRtcClient.createOffer(id);
    }

    public WebRtcClient getWebRtcClient() {
        return mRtcClient;
    }

    public void setPermissionCallBack(PermissionCallBack callBack) {
        mPermissionCallBack = callBack;
    }

    public SignalClient getSignalClient() {
        return mSignalClient;
    }

    public void release() {
        mRtcClient.unRegisterPeerListener(this);
        mSignalClient.unRegisterSignaListener(this);
        mSignalClient.release();
        mRtcClient.release();
        mRtcClient = null;
        mSignalClient = null;
        clientManager = null;
    }

    public boolean isConnected(String id) {
       return mRtcClient.isComplete(id);
    }

    public void sendData(String id,byte buffer[]) {
        mRtcClient.sendMsg(id,buffer);
    }

    @Override
    public void onOfferAnswerCreated(String id, String type, JSONObject payload) {
        try {
            Log.v(TAG,"onOfferAnswerCreated id = " + id);
            mSignalClient.sendMessage(id,type,payload);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onIceCandidate(String id, String type, JSONObject payload) {
        try {
            mSignalClient.sendMessage(id,type,payload);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onIceDisconnect(String id) {
        mRtcClient.closePeer(id);
    }

    @Override
    public void onIceConnect(String id) {
        System.out.println("onIceConnect = " + id);
    }

    @Override
    public void onCompleted(String id) {
        mRtcClient.sendMsg(id,"hello world".getBytes());
    }

    @Override
    public void onAddRemoteStream(String id, MediaStream mediaStream) {
    }

    @Override
    public void onMessage(String id, byte[] buffer) {
        System.out.println("id = " + id);
        System.out.println(new String(buffer));
    }

    @Override
    public void onOffer(String from, SessionDescription sdp) {
        Log.v(TAG,"onOffer from = " + from);
        mRtcClient.createAnswer(from,sdp);
    }

    @Override
    public void onAnswer(String from, SessionDescription sdp) {
        Log.v(TAG,"onAnswer from = " + from);
        mRtcClient.receiveAnswer(from,sdp);
    }

    @Override
    public void onCandidate(String from, IceCandidate candidate) {
        mRtcClient.addCandidate(from,candidate);
    }


    public interface PermissionCallBack {

        public boolean acceptConnect();
    }
}
